#pragma once
#include <iostream>
#include<unordered_map>
#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstring>
#include<unistd.h>
#include<fstream>

#include"udp_server.hpp"
#include"inet_addr.hpp"
#include"log.hpp"

#define default_fd -1
class DictServer{
    public:
        DictServer(uint16_t port):_port(port),_socketfd(-1){
            _socketfd=socket(AF_INET,SOCK_DGRAM,0);
            if(_socketfd==-1){
                std::cout<<"Error in creating socket"<<std::endl;
                return;
            }
            struct sockaddr_in socket_addr;
            memset(&socket_addr,0,sizeof(socket_addr));
            socket_addr.sin_family=AF_INET;
            socket_addr.sin_addr.s_addr=INADDR_ANY;
            socket_addr.sin_port=htons(port);
            //绑定端口
            if(bind(_socketfd,(struct sockaddr*)&socket_addr,sizeof(socket_addr))==-1){
                std::cout<<"绑定失败"<<std::endl;
                perror("bind failed");
                close(_socketfd);
                _socketfd=default_fd;
                return;
            }
            LOG(ly::LogLevel::INFO)<<"服务器启动成功,端口号为 "<<port;
        }
        void Send(const std::string& message){
            if(_socketfd==-1){
                LOG(ly::LogLevel::ERROR)<<"套接字未创建";
                return;
            }
        }
        //添加词典
        void BulidDict(){
            std::ifstream ifs("./dict.txt");
            if(!ifs.is_open()){
                LOG(ly::LogLevel::WARNING)<<"字典文件打开失败";
                return;
            }
            std::string  line,key,val,seg=":";
            while(std::getline(ifs,line)){
                auto it=line.find(seg);
                key=line.substr(0,it);
                val=line.substr(it+1,line.size()-1);
                _dict[key]=val;
            }
        }
        bool AddDict(const std::string& key,const std::string& val){
             std::ofstream ofs("./dict.txt",std::ios::app);
            if(!ofs.is_open()){
                LOG(ly::LogLevel::WARNING)<<"字典文件打开失败";
                return false;
            }
            _dict[key]=val;
            std::string  line=key+":"+val+"\n";
            ofs<<line;
            return true;
        }
        bool DelDict(const std::string& key){
            if(_dict.find(key)==_dict.end()){
                LOG(ly::LogLevel::WARNING)<<"词典中不存在该词";
                return false;
            }
            _dict.erase(key);
            return true;
        }
        void SaveDict(){
            std::ofstream ofs("./dict.txt");
            if(!ofs.is_open()){
                LOG(ly::LogLevel::WARNING)<<"字典文件打开失败";
                return;
            }
        }
        void Start(){
            BulidDict();
            for(auto it=_dict.begin();it!=_dict.end();++it){
                std::cout<<it->first<<":"<<it->second<<std::endl;
            }
            char buffer[1024];
            const char* val=nullptr;
            while(true){
                memset(buffer,0,sizeof(buffer));
                struct sockaddr_in clientaddr;
                socklen_t addrlen=sizeof(clientaddr);
                memset(&clientaddr,0,addrlen);
                ssize_t n=recvfrom(_socketfd,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&clientaddr,&addrlen);
                if(n==-1){
                    std::cout<<"读取错误"<<std::endl;
                    perror("recvfrom failed");
                    close(_socketfd);
                    _socketfd=default_fd;
                    return;
                }
                else{
                    InetAddr client_addr(clientaddr);
                    std::cout<<"接收到消息: "<<buffer<<" 来自 "<<client_addr.PrintDebug()<<std::endl;
                    auto it=_dict.find(buffer);
                    if(it==_dict.end()){
                        val="";
                    }
                    else{
                        val=it->second.c_str();
                    }
                    sendto(_socketfd,val,it->second.length(),0,(struct sockaddr*)&clientaddr,addrlen);
                }
            }
        }
        void getLocalAddr() {
            struct sockaddr_in addr;
            socklen_t len = sizeof(addr);
            // 获取套接字绑定的本地地址
            if (getsockname(_socketfd, (struct sockaddr*)&addr, &len) == -1) {
                perror("getsockname failed");
                return;
            }
            // 转换IP为字符串
            char ip[INET_ADDRSTRLEN];
            inet_ntop(AF_INET, &addr.sin_addr, ip, sizeof(ip));
            // 转换端口为本地字节序
            uint16_t port = ntohs(addr.sin_port);
            std::cout << "本地绑定的IP: " << ip << ", 端口: " << port << std::endl;
        }
        ~DictServer(){
            if(_socketfd!=default_fd){
                close(_socketfd);
            }
        }
    private:
        std::unordered_map<std::string,std::string> _dict;
        int _socketfd;
        uint16_t _port;
        
};